import dash
import dash_bootstrap_components as dbc
from dash import Output, Input, ClientsideFunction, State

from data import *

app = dash.Dash(__name__,
                meta_tags=[{
                    "name": "viewport",
                    "content": "width=device-width, height=device-height, initial-scale=1, maximum-scale=1",
                }],
                external_scripts=["/assets/jquery-3.6.0.min.js",
                                  "/assets/script.js"],
                external_stylesheets=[dbc.themes.BOOTSTRAP,
                                      "/assets/custom.css",
                                      ],
                index_string='''
                <!DOCTYPE html>
                <html>
                    <head>
                        {%metas%}
                        <title>iPS</title>
                        <link rel="icon" href="/assets/Qline.svg">
                        <link rel="stylesheet" href="/assets/bootstrap.min.css">
                        <link rel="stylesheet" href="/assets/custom.css">
                    </head>
                    <body>
                        {%app_entry%}
                        <footer>
                            {%config%}
                            {%scripts%}
                            {%renderer%}
                        </footer>
                    </body>
                </html>
                '''
                )
server = app.server
app.prevent_initial_callbacks = True
app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
app.config.suppress_callback_exceptions = True

breadcrumb = dbc.Breadcrumb(
    items=[
        {"label": "iPS", "href": "https://ips.uaes.com/", "external_link": True},
        {"label": "数据服务"},
        {"label": "产品专家", "active": True},
    ],
)

scope = html.H3("帮助产品专家对失效进行分类跟踪")

tab1_filter = html.P("选择筛选器，查看数量，确认筛选条件")

tab2_category_header = html.P([
    "对分析结论进行分类，分类的名称可以修改，点击计数可以查看失效信息",
    dbc.Button(id="category_update", children="更新分类"),
    dbc.Switch(id="mode_filter_toggle", label="打开搜索框", value=True)
])
tab2_category = dbc.Container([
    dbc.Row(tab2_category_header),
    dbc.Row([
        dbc.Col(tab2_mode_cate_table, width=8),
        dbc.Col(tab2_cate_table, width=4)
    ])
])

tab3_output = dbc.Container([
    dbc.Row(html.P("输出分类后的数据，常用统计图表")),
    dbc.Row(tab3_output_table)
])

tabs = dbc.Tabs([
    dbc.Tab(tab1_filter, label="筛选数据"),
    dbc.Tab(tab2_category, label="失效分类"),
    dbc.Tab(tab3_output, label="统计结果"),
])
canvas_failure = dbc.Offcanvas(
    failure_table,
    id="failure_canvas",
    close_button=False,
    placement="bottom",
    is_open=False,
)
app.layout = dbc.Container([
    breadcrumb,
    tabs,
    canvas_failure
],
    fluid=True
)

clientside_callback = 'clientside_callback'
# 开关失效清单
app.clientside_callback(
    ClientsideFunction(namespace="clientside", function_name="toggle_hints"),
    Output("failure_canvas", "is_open"),
    Input('mode_cate_table', 'active_cell'),
)
# 开关搜索栏
app.clientside_callback(
    ClientsideFunction(namespace="clientside", function_name="toggle_filter"),
    Output("mode_cate_table", "filter_action"),
    Input('mode_filter_toggle', 'value'),
    State("mode_cate_table", "filter_action"),
)


@app.callback(
    Output("failure_table", "data"),
    Input('mode_cate_table', 'active_cell'),
)
def get_failure_hint(cell_dict):
    if cell_dict is None or cell_dict['column_id'] != 'qty':
        return dash.no_update
    else:
        problem_id = cell_dict['row_id']
        print("查看问题数据", problem_id)
        df_temp = df_test[df_test['结论编号'] == problem_id]
        return df_temp.to_dict('records')


@app.callback(
    Output('cate_table', 'data'),
    Output('cate_table', 'style_data_conditional'),
    Input('mode_cate_table', 'data'),
    State('mode_cate_table', 'columns'))
def cate_count(data, columns):
    df = pd.DataFrame(data, columns=[c['id'] for c in columns])
    df_CATE = df.groupby('cate')['qty'].sum().reset_index()
    df_CATE.sort_values(by='qty', ascending=False, inplace=True)
    return df_CATE.to_dict('records'), (
        data_bars(df_CATE, 'qty')
    )


@app.callback(
    Output('output_table', 'data'),
    Output('output_table', 'columns'),
    Output('output_table', 'style_data_conditional'),
    Input('category_update', 'n_clicks'),
    State('mode_cate_table', 'data'),
    State('mode_cate_table', 'columns'))
def output_display(n, mode_cate, columns):
    df = pd.DataFrame(mode_cate, columns=[c['id'] for c in columns])
    df_output = df_test.merge(df, left_on='结论编号', right_on='id').drop(['id', 'mode', 'qty'], axis=1)
    df_output.rename(columns={'cate': '结论分类'}, inplace=True)
    pivot1 = df_output.groupby(['结论分类', '生产月份'])['失效编号'].count().unstack()
    heatmap_styles, _ = discrete_background_color_bins(pivot1)
    pivot1['总计'] = pivot1.sum(axis=1)
    pivot1.sort_values('总计', ascending=False, inplace=True)
    pivot1.reset_index(inplace=True)
    return pivot1.to_dict('records'), [{'name': i, 'id': i} for i in pivot1.columns], heatmap_styles + data_bars(pivot1,
                                                                                                                 '总计')


if __name__ == '__main__':
    app.run_server(debug=False)
